﻿using Microsoft.VisualStudio.Text;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace VSAdditionalCommands.Commands
{
    [Command(PackageIds.DublicateMethodCommand)]
    internal sealed class DublicateMethodCommand : BaseCommand<DublicateMethodCommand>
    {
        protected override async Task ExecuteAsync(OleMenuCmdEventArgs e)
        {
            await Package.JoinableTaskFactory.SwitchToMainThreadAsync();
            DocumentView docView = await VS.Documents.GetActiveDocumentViewAsync();
            if (docView?.TextView == null) return;
            SnapshotPoint position = docView.TextView.Caret.Position.BufferPosition;

            if (docView.TextBuffer != null)
            {
                var snapshot = docView.TextBuffer.CurrentSnapshot;
                var text = snapshot.GetText(new Span(0, position.Position + 1));
                var methodBeginPositionRegex = new Regex(@"\s*(private|public|protected)", RegexOptions.RightToLeft);
                var methodBeginPosition = methodBeginPositionRegex.Match(text);
                if (methodBeginPosition.Success)
                {
                    var startMethodToEndText = snapshot.GetText(new Span(methodBeginPosition.Index, snapshot.Length - methodBeginPosition.Index));

                    int curlyBracesOpenedCount = -1;
                    int pos = 0, closeBracePos = -1;
                    var charr = startMethodToEndText.ToCharArray();
                    do
                    {
                        char ch = charr[pos++];
                        if (ch == '{')
                        {
                            if (curlyBracesOpenedCount == -1)
                            {
                                curlyBracesOpenedCount = 1;
                            }
                            else
                            {
                                curlyBracesOpenedCount++;
                            }
                        }
                        else if (ch == '}')
                        {
                            if (curlyBracesOpenedCount > 0)
                            {
                                curlyBracesOpenedCount--;
                                if(curlyBracesOpenedCount == 0)
                                {
                                    closeBracePos = pos;
                                }
                            }
                            else
                            {
                                Debug.WriteLine($"WRONG curlyBracesOpenedCount {curlyBracesOpenedCount}");
                                return;
                            }
                        }
                    }
                    while ((curlyBracesOpenedCount == -1
                            || curlyBracesOpenedCount > 0)
                                && pos < charr.Length);

                    var methodText = startMethodToEndText.Substring(0, pos);
                    docView.TextBuffer?.Insert(methodBeginPosition.Index + closeBracePos, "\n" + methodText);
                    snapshot = docView.TextBuffer.CurrentSnapshot;
                    docView.TextView.Selection.Select(new VirtualSnapshotPoint(snapshot, methodBeginPosition.Index + closeBracePos + 2)
                        , new VirtualSnapshotPoint(snapshot, methodBeginPosition.Index + closeBracePos + methodText.Length + 1));
                }

            }
        }
    }
}
